#include "anchor.h"


TL::String Anchor::m_CookieString = "";


DWORD WINAPI json_thread(LPVOID thread_param)
{
    Anchor *anchor = (Anchor *)thread_param;

    if (anchor->m_RemainingPurchases < 0) {
        return 0;
    }

    HINTERNET hInternet = InternetOpenA("Googlebot/2.1 (+http://www.google.com/bot.html)", INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0);
    TL::String json;
    char tmp_str[4096];
    const int tmp_str_size = 4096;
    int text_pos;
    bool got_market_url = false;
    std::ofstream log(("data/anchor_(" + anchor->m_SearchQuery + ").txt").GetCharString(), std::ofstream::out);

    InternetSetCookieA("http://steamcommunity.com", 0, "Steam_Language = english");
    InternetSetCookieA("http://steamcommunity.com", 0, ("steamLogin = " + Anchor::m_CookieString).GetCharString());
    
    while (anchor->m_Runner->IsRunning()) {
        Sleep(50);

        HINTERNET hUrl = InternetOpenUrlA(hInternet, ("http://steamcommunity.com/market/search/render/?query=" + anchor->m_SearchQuery + "&start=0&count=1").GetCharString(), 0, 0, 0, 0);

        json = "";

        if (hUrl != 0) {
            DWORD dwRead = 0;

            do {
                InternetReadFile(hUrl, tmp_str, tmp_str_size - 1, &dwRead);
                tmp_str[dwRead] = 0;

                json = json + tmp_str;
            } while (dwRead != 0);
        }

        InternetCloseHandle(hUrl);

        // лишнее
        json.Remove("\\n");
        json.Remove("\\r");
        json.Remove("\\t");
        json.Remove("\\");
        json.Remove("&#36;"); // значок доллара

        // считывание ссылки на магазин
        if (!got_market_url) {
            text_pos = json.FindFirstSubstringEnd("market_listing_row_link");
            if (text_pos != -1) {
                text_pos = json.FindFirstSubstring("http", text_pos + 1);
                if (text_pos != -1) {
                    int i = 0, j = text_pos;

                    while (json[j] && json[j] != '\"') {
                        tmp_str[i++] = json[j++];
                    }

                    tmp_str[i] = 0;

                    anchor->m_MarketURL = tmp_str;
                    anchor->m_MarketURL.Remove("\\");
                    anchor->m_MarketURL.Remove("\"");

                    got_market_url = true;
                }
            }
        }

        // считывание цены
        text_pos = json.FindFirstSubstringEnd("Starting at");
        if (text_pos != -1) {
            int i = 0, j = text_pos + 1;

            while (json[j] && !isdigit(json[j])) {
                j++;
            }

            while (json[j] && (isdigit(json[j]) || json[j] == ',' || json[j] == '.')) {
                if (json[j] == ',') {
                    tmp_str[i] = '.';
                }
                else {
                    tmp_str[i] = json[j];
                }

                i++;
                j++;
            }

            tmp_str[i] = '\0';

            anchor->m_CurrentPrice = tmp_str;
        }
        else {
            anchor->m_CurrentPrice = 0.0;
        }

        if (log.good()) {
            log << "cur price: " << anchor->m_CurrentPrice.GetNumber() << std::endl;
            log.flush();
        }

        if (!anchor->m_MarketURL.IsEmpty() && anchor->m_CurrentPrice.GetNumber() > 0.0 && anchor->m_CurrentPrice.GetNumber() <= anchor->m_TargetPrice.GetNumber()) {
            anchor->m_Runner->Stop();

            anchor->m_TargetQueue->Push(anchor);
        }
    }

    InternetCloseHandle(hInternet);

    log.close();

    return 0;
}

Anchor::Anchor(TL::String search_query, TL::String target_price, int total_number_of_purchases, TL::Queue_TS<Anchor *> *target_queue)
{
    m_MarketURL = "";
    m_RemainingPurchases = total_number_of_purchases;
    m_Runner = new TL::Runner(true);
    m_SearchQuery = search_query;
    m_TargetPrice = target_price;
    m_TargetQueue = target_queue;

    m_JSONThread = CreateThread(0, 0, json_thread, this, 0, 0);
}
Anchor::~Anchor()
{
    if (m_JSONThread) {
        TerminateThread(m_JSONThread, 0);
        CloseHandle(m_JSONThread);
    }
}

const TL::String &Anchor::GetMarketURL() const
{
    return m_MarketURL;
}
const int &Anchor::GetRemainingPurchases() const
{
    return m_RemainingPurchases;
}
const TL::String &Anchor::GetSearchQuery() const
{
    return m_SearchQuery;
}
const TL::Price &Anchor::GetTargetPrice() const
{
    return m_TargetPrice;
}
void Anchor::Restart()
{
    if (m_JSONThread) { // thread is running
        Stop();
    }
    
    m_Runner->Start();

    m_JSONThread = CreateThread(0, 0, json_thread, this, 0, 0);
}
void Anchor::Stop()
{
    m_Runner->Stop();

    if (m_JSONThread) {
        DWORD stop_result = WaitForSingleObject(m_JSONThread, 5000);

        if (stop_result == WAIT_ABANDONED || stop_result == WAIT_TIMEOUT) {
            TerminateThread(m_JSONThread, 1);
        }

        CloseHandle(m_JSONThread);
        m_JSONThread = 0;
    }
}

Anchor &Anchor::operator++()
{
    m_RemainingPurchases++;

    return *this;
}
Anchor &Anchor::operator--()
{
    m_RemainingPurchases--;

    return *this;
}
